﻿/****************************************************************
*   作者：Morain
*   创建时间：2018/2/8 22:05:02
*   描述说明：
*****************************************************************/
using ETSModel;
using MongoDB.Bson.Serialization.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Hotfix
{
  /// <summary>
  /// 实体
  /// 实体继承组件
  /// </summary>
  public abstract class Entity : Component
  {
    private HashSet<Component> components;

    /// <summary>
    /// 组件列表
    /// </summary>
    private Dictionary<Type, Component> componentDict;

    public Entity()
    {
      this.Id = IdGenerater.GeneraterId();
      this.components = new HashSet<Component>();
      this.componentDict = new Dictionary<Type, Component>();
    }

    public Entity(long id)
    {
      this.Id = id;
      this.components = new HashSet<Component>();
      this.componentDict = new Dictionary<Type, Component>();
    }

    /// <summary>
    /// 添加组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T AddComponent<T>() where T : Component, new()
    {
      Component component;
      Type t = typeof(T);
      if (componentDict.TryGetValue(t, out component))
      {
        Log.Error($"此组件已经存在：${t}");
        return null;
      }

      T comp = ComponentFactory.Create<T>(this);
      componentDict.Add(t, comp);
      if (comp is ISerializeToEntity)
      {
        this.components.Add(comp);
      }
      return comp;
    }

    public T AddComponent<T, P>(P p) where T : Component, new()
    {
      Component component;
      Type t = typeof(T);
      if (componentDict.TryGetValue(t, out component))
      {
        Log.Error($"此组件已经存在：${t}");
        return null;
      }

      T comp = ComponentFactory.Create<T, P>(this, p);
      componentDict.Add(t, comp);
      if (comp is ISerializeToEntity)
      {
        this.components.Add(comp);
      }
      return comp;
    }

    public T AddComponent<T, P1, P2>(P1 p1, P2 p2) where T : Component, new()
    {

      Component component;
      Type t = typeof(T);

      if (componentDict.TryGetValue(t, out component))
      {
        Log.Error($"此组件已经存在：${t}");
        return null;
      }

      T comp = ComponentFactory.Create<T, P1, P2>(this, p1, p2);
      componentDict.Add(t, comp);
      if (comp is ISerializeToEntity)
      {
        this.components.Add(comp);
      }
      return comp;
    }

    /// <summary>
    /// 移除组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public void RemoveComponent<T>() where T : Component
    {
      componentDict.Remove(typeof(T));
    }

    /// <summary>
    /// 获取组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T GetComponent<T>() where T : Component
    {
      Component t;
      if (!this.componentDict.TryGetValue(typeof(T), out t)) return null;

      return (T)t;
    }

    public Component[] GetComponents()
    {
      return this.componentDict.Values.ToArray();
    }

    public override void Dispose()
    {
      if (this.Id == 0)
      {
        return;
      }

      base.Dispose();

      foreach (Component component in this.GetComponents())
      {
        try
        {
          component.Dispose();
        }
        catch (Exception e)
        {
          Log.Error(e.ToString());
        }
      }

      this.components.Clear();
      this.componentDict.Clear();
    }
  }
}